package leetcode_core.leetcode_3;

import java.util.*;

public class RectangleArea {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        double[][] rectangles = new double[n][4];
        for (int i = 0; i < n; i++) {
            double x1 = scanner.nextDouble(),y1 = scanner.nextDouble(),x2 = scanner.nextDouble(),y2= scanner.nextDouble();
            rectangles[i][0] = x1;
            rectangles[i][1] = y1;
            rectangles[i][2] = x2;
            rectangles[i][3] = y2;
        }
        double ans = rectangleArea(rectangles);
        System.out.println(String.format("%.2f",ans));
    }

    public static int MOD = (int)1e9+7;
    public static double rectangleArea(double[][] rectangles) {
        //1.首先搞清楚rectangle是[x1,y1,x2,y2]
        //然后咱们把矩形按照x进行排序,从小到大,先把x拿出来
        double ans = 0;
        List<Double> xes = new ArrayList<>();
        for (double[] rectangle : rectangles) {
            xes.add(rectangle[0]);
            xes.add(rectangle[2]);
        }
        Collections.sort(xes);
        for(int i = 1;i<xes.size();i++){
            //2.计算出宽度,取出端点
            double front = xes.get(i-1);//线段的起始端点
            double backend = xes.get(i);//线段的结束端点
            double len = backend-front;
            if(len == 0){
                continue;//宽度为0,没有计算价值
            }
            //然后计算所有在这个x范围的内矩形,我们先把y给它给拿进来
            List<double[]> lines = new ArrayList<>();//这个代表着在区间里面,所有的y线段
            for (double[] rectangle : rectangles) {
                //首先搞清楚rectangle是[x1,y1,x2,y2]
                //x1是左下角
                //x2是右上角
                //然后找出来所有和x有交集的
                if(rectangle[0]<= front && rectangle[2]>= backend){
                    //我们将这一段y给加入到候选区间中
                    lines.add(new double[]{rectangle[1],rectangle[3]});
                }
            }
            //然后就开始转化为了`区间合并问题了`
            if(lines.size() == 0){
                continue;
            }
            double[][] intervals = lines.toArray(new double[0][]);
            //首先按照起点进行排序
            Arrays.sort(intervals, new Comparator<double[]>() {
                @Override
                public int compare(double[] o1, double[] o2) {
                    return (int)(o1[0]-o2[0]);
                }
            });
            long total = 0;
            double[] cur = intervals[0];
            for(int j = 0;j<intervals.length;j++){
                double[] next = intervals[j];
                if(cur[1] >= next[0]){
                    cur[1] = Math.max(cur[1],next[1]);
                }else{
                    total += cur[1] - cur[0];
                    cur = next;
                }
            }
            total += cur[1] - cur[0];
            ans += total*len;
        }
        return ans;
    }
}
